package stack;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * @description:
 * @title: PolandNotationDemo
 * @author: zp
 * @date: 2021/11/7 15:59
 * 解析后缀表达式 计算结果 为了方便逆波兰表达式 数字和字符使用空格隔开
 * 逆波兰计算器
 */
public class PolandNotationDemo {
    public static void main(String[] args) {
        System.out.println(expression(getHouZhui("1+((2+3)*4)-5")));
    }
    /**
     * @description: 把字符串转化成一个list集合
     * @author: zp
     * @date: 2021/11/7 20:40
     * @param: null
     * @return:
     */
    public static List<String> getListString(String str){
        String[] strings = str.split(" ");
        List<String> list= new ArrayList<>();
        for (String s:strings) {
            list.add(s);
        }
        return list;
    }

    /**
     * @description: 把字符串转化成一个list集合
     * @author: zp
     * @date: 2021/11/7 20:40
     * @param: null
     * @return:
     */
    public static List<String> getListStr(String str){
        char[] strings = str.toCharArray();
        List<String> list= new ArrayList<>();
        int i=0;
        String string;
        do {
            if(strings[i]<48 || strings[i]>57){
                list.add(strings[i]+"");
                i++;
            }else {
                string="";
                while (i<str.length() && (strings[i]>=48 && strings[i]<=57)){
                    string+=strings[i];
                    i++;
                }
                list.add(string);
            }
        }while (i<str.length());
        return list;
    }

    public static int expression(List<String> list){
        Stack<String> stack=new Stack<>();
        int res;
        for (int i = 0; i <list.size() ; i++) {
            if(isOper(list.get(i))){
                res=cal(Integer.parseInt(stack.pop()),Integer.parseInt(stack.pop()),list.get(i));
                stack.push(String.valueOf(res));
            }else {
                stack.push(list.get(i));
            }
        }
        return Integer.parseInt(stack.pop());
    }
    /**
     * @description:
     * @author: zp
     * @date: 2021/11/7 15:26
     * @param: val
     * @return: boolean
     * 判断是否为符号
     */
    public static boolean isOper(String val){
        return  "+".equals(val) || "*".equals(val) || "/".equals(val) || "-".equals(val);
    }
    /**
     * @description:
     * @author: zp
     * @date: 2021/11/7 15:25
     * @param: num1
     * @param: num2
     * @param: oper
     * @return: int
     * 计算
     */
    public static int cal(int num1 ,int num2,String oper){
        int res=0;
        switch (oper){
            case "+":
                res = num1+num2;
                break;
            case "-":
                res = num2-num1;
                break;
            case "*":
                res = num1*num2;
                break;
            case "/":
                res=num2/num1;
                break;
            default:break;
        }
        return res;
    }
    /**
     * @description: 中缀表达式转换后缀表达式
     * @author: zp
     * @date: 2021/11/9 21:18
     * @param: str
     * @return: java.lang.String
     */
    public static List<String> getHouZhui(String str) {
        List<String> numStack = new ArrayList<>();
        Stack<String> characterStack = new Stack<>();

        List<String> list=getListStr(str);
        for (String item:list) {
            if(item.matches("\\d+")){
                numStack.add(item);
            }else if("(".equals(item)){
                characterStack.push(item);
            }else if(")".equals(item)){
                while (!"(".equals(characterStack.peek())){
                    numStack.add(characterStack.pop());
                }
                characterStack.pop();
            }else {
                while (!characterStack.empty() && (priority(item)<=priority(characterStack.peek()))){
                    numStack.add(characterStack.pop());
                }
                characterStack.push(item);
            }
        }

        while (!characterStack.empty()){
            numStack.add(characterStack.pop());
        }

        return numStack;
}

    /**
     * @description:
     * @author: zp
     * @date: 2021/11/7 15:26
     * @param: val
     * @return: boolean
     * 判断是否为符号
     */
    public static boolean isOper(char val){
        return  val=='+' || val=='*' || val=='/' || val=='-';
    }

    /**
     * @description:
     * @author: zp
     * @date: 2021/11/7 15:25
     * @param: num1
     * @param: num2
     * @param: oper
     * @return: int
     * 计算
     */
    public static int cal(int num1 ,int num2,int oper){
        int res=0;
        switch (oper){
            case '+':
                res = num1+num2;
                break;
            case '-':
                res = num2-num1;
                break;
            case '*':
                res = num1*num2;
                break;
            case '/':
                res=num2/num1;
                break;
            default:break;
        }
        return res;
    }

    /**
     * @description:
     * @author: zp
     * @date: 2021/11/7 15:26
     * @param: oper
     * @return: int
     * 判断输入符号优先级
     */
    public static int priority(int oper){
        if(oper=='*' || oper == '/'){
            return 1;
        }else if(oper=='+' || oper == '-'){
            return 0;
        }else {
            return -1;
        }
    }

    /**
     * @description:
     * @author: zp
     * @date: 2021/11/7 15:26
     * @param: oper
     * @return: int
     * 判断输入符号优先级
     */
    public static int priority(String oper){
        if("*".equals(oper) || "/".equals(oper)){
            return 1;
        }else if("+".equals(oper) || "-".equals(oper)){
            return 0;
        }else {
            return -1;
        }
    }
}
